AWS CLIからCloudFormation でユーザとロールを作成して、流れるようにスイッチロールの確認をしてみた
最近は、ABACばっかりやってるAWS 事業本部 梶原@福岡オフィスです。
ABAC(属性ベースのアクセスコントロール )を実施する際、ポリシーは同一にして、スケールすることができるのですが、ユーザやロールの確認作業は必要になってきます。 とはいえ、様々な属性値のユーザの確認作業を手作業でやるのは結構大変です。
ということで検証作業を楽にするため、ユーザー作成、ロール作成部分をTemplate化しました。必要に応じて修正(タグ値を追加など)して、ご自由にお使いください また流れで、ロールの検証を行いたいため、スイッチロールを楽にするために認証情報を取得しやすくしています。 credentialsの設定や、configの設定って微妙にはまりがちなのでなるべく簡単に定型作業でできるようにしています。でわでわ
Templateの説明
Template全体は、Githubへのリンクを参照してください
ユーザー、ロール作成用 CloudFormation テンプレート
https://github.com/ambasad/devio-blog-cfn/raw/master/iam/cfn-iam-user.yml
ユーザ作成部分
パラメータで指定したRoleへのAssumeRoleだけ可能なユーザを作成しています
IAMManagedPolicyAssumeRole: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: access-assume-role Path: / PolicyDocument: !Sub | { "Version": "2012-10-17", "Statement": [ { "Sid": "AssumeRole", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::${AWS::AccountId}:role/${RoleName}" } ] } IAMUser1: Type: AWS::IAM::User Properties: Path: / UserName: !Ref UserName ManagedPolicyArns: - !Ref IAMManagedPolicyAssumeRole
ロール作成部分
信頼されたエンティティに作成したユーザを指定しています
IAMRole1: Type: AWS::IAM::Role Properties: Path: / RoleName: !Ref RoleName AssumeRolePolicyDocument: !Sub | { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Principal": {"AWS":"${IAMUser1.Arn}"} } ] } MaxSessionDuration: 3600
API アクセスキー作成部分
API アクセスキーを作成します
IAMAccessKeyUser1: Type: AWS::IAM::AccessKey Properties: UserName: !Ref IAMUser1
API アクセスキー保存部分
作成したAPIキーをSecretsManagerに保存しています。 後で使いやすいように認証情報ファイル(credentials)で使いやすいように整形しています 後程、設定情報ファイル(.aws/credentials)に設定します。
※ 認証情報をSecretsManager保持することになるため、必要に応じてパラメータのKmsKeyIdを指定し 作成したユーザだけが復号、取得できるようにするなどの対応を推奨します。
SecretUser1: Type: AWS::SecretsManager::Secret Properties: Name: !Sub ${IAMUser1}-credentials KmsKeyId: !If [UseKmsKey, !Ref KmsKeyId, !Ref "AWS::NoValue"] SecretString: !Sub | [${IAMUser1}] aws_access_key_id = ${IAMAccessKeyUser1} aws_secret_access_key = ${IAMAccessKeyUser1.SecretAccessKey}
こんな感じの文字列が設定されます
[UserA] aws_access_key_id = xxxxxxxxxxxxxxxxxx aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
認証設定情報保存部分
こちらは認証情報を含まないため、設定ファイル(config)で使いやすいように整形して保存しています。 後程、設定情報ファイル(.aws/config)に設定します。
内容は追加したユーザから作成したロールにスイッチロールする設定になります
IAMRole1Config: Type: AWS::SSM::Parameter Properties: Type: String Value: !Sub | [profile ${IAMRole1}] role_arn = ${IAMRole1.Arn} source_profile = ${IAMUser1}
こんな感じの文字列が設定されます
[profile RoleA] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleA source_profile = UserA
出力部
使用しやすいように、作成したユーザやロールをパラメータにしたコマンドを出力しています。
Outputs: User1Credentials: Value: !Sub | aws secretsmanager get-secret-value --secret-id ${SecretUser1} --query 'SecretString' --output text >> ~/.aws/credentials User1Config: Value: !Sub | aws ssm get-parameters --names ${IAMRole1Config} --query 'Parameters[].Value' --output text >> ~/.aws/config User1SwitchRole: Value: !Sub | aws sts get-caller-identity --profile ${IAMRole1}
AWS CLIからCloudFormationの実行
なお、CloudFormationの実行権限等はあるものとして進めています。
Stack作成
テンプレート cfn-iam-user.yml を実行して、スタック作成します。 ユーザ名、ロール名などはパラメータで指定できるようにしていますが、ここではデフォルト値(UserA, RoleA)を使用します。
template=cfn-iam-user aws cloudformation create-stack --stack-name $template \ --template-body "file://./$template.yml" \ --capabilities CAPABILITY_NAMED_IAM
AWS CLIからCloudFormationの実行結果を取得し、認証情報を設定
認証情報の取得
認証情報をSecretsManagerから取得します。CloudFormationの出力に取得用のコマンドを設定しているので取得します。
aws cloudformation describe-stacks --stack-name $template \ --query 'Stacks[].Outputs[?OutputKey==`User1Credentials`].OutputValue' \ --output text
以下のようなコマンドが取得できるかと思いますので実行します。 取得した認証情報を ~/.aws/credentials に追記しています。
aws secretsmanager get-secret-value --secret-id arn:aws:secretsmanager:ap-northeast-1:XXXXXXXXXXXX:secret:UserA-credentials-XXXXX --query 'SecretString' --output text >> ~/.aws/credentials
必要に応じて実際に設定(追記)されているか確認してみます。
cat ~/.aws/credentials
認証設定の取得
認証設定情報をSystemsManager のパラメータから取得します。CloudFormationの出力に取得用のコマンドを設定しているので取得します。
aws cloudformation describe-stacks --stack-name $template \ --query 'Stacks[].Outputs[?OutputKey==`User1Config`].OutputValue' \ --output text
以下のようなコマンドが取得できるかと思いますので実行します。 取得した認証設定情報を ~/.aws/config に追記しています。
aws ssm get-parameters --names CFN-IAMRole1Config-XXXXXXXXXXXX --query 'Parameters[].Value' --output text >> ~/.aws/config
必要に応じて実際に設定(追記)されているか確認してみます。
cat ~/.aws/config
AWS CLIからスイッチロール権限の確認
スイッチロールの確認
profileで指定できるようにしてますのでユーザの認証、スイッチロールが実行できるか確認します。
aws cloudformation describe-stacks --stack-name $template \ --query 'Stacks[].Outputs[?OutputKey==`User1SwitchRole`].OutputValue' \ --output text
以下のようなコマンドが取得できるかと思いますので実行します。 特にエラー等が発生せずに、Arnが取得できていればユーザの認証、スイッチロールは成功しています
aws sts get-caller-identity --profile UserA { "UserId": "XXXXXXXXXXXXXXXXXXXXX", "Account": "XXXXXXXXXXXX", "Arn": "arn:aws:iam::XXXXXXXXXXXX:user/UserA" } aws sts get-caller-identity --profile RoleA { "UserId": "XXXXXXXXXXXXXXX:botocore-session-1586854302", "Account": "XXXXXXXXXXXXXXX", "Arn": "arn:aws:sts::XXXXXXXXXXXXXXX:assumed-role/RoleA/botocore-session-XXXXXXXXXXXXXXX" }
おまけ 既存のRoleにポリシーを追加してみる
これだけだと、ただスイッチロールの検証だけですので、必要なポリシーを定義した管理ポリシーを作成したロールに追加します。
サンプルとしてS3の権限を作成した管理ポリシーを先ほど作成したロールに追加します。
template=cfn-add-policy aws cloudformation create-stack --stack-name $template --template-body "file://./$template.yml" \ --parameters "ParameterKey=Roles, ParameterValue=RoleA" \ --capabilities CAPABILITY_NAMED_IAM
スタックの作成、成功後、にprofileを指定して、S3へのアクセス権限等を確認します。
aws s3 ls --profile RoleA
まとめ
コマンドラインでの作業でなるべく完結するようにしてみました。コマンドライン(AWS CLI)で実施できるところまで行けば、検証含めた自動化もやりやすくなるかと思います。 今回公開しているテンプレートは基本的な部分にそぎおとしてますが、テンプレートの素材としては使いやすいようにしたつもりですので、どなたかのお役に立てれば幸いです。
後片付け
検証が終了したら、スタック、リソースは削除してしまいます。便利です。
template=cfn-iam-user aws cloudformation delete-stack --stack-name $template
認証情報(~/.aws/credentials)、認証設定情報(~/.aws/config)も適時消してください。
テンプレートファイル
ユーザー、ロール作成用 CloudFormation テンプレート https://github.com/ambasad/devio-blog-cfn/raw/master/iam/cfn-iam-user.yml
既存のロールへの管理ポリシーの追加用 CloudFormation テンプレート
https://github.com/ambasad/devio-blog-cfn/raw/master/iam/cfn-add-policy.yml
参考情報
https://aws.amazon.com/jp/premiumsupport/knowledge-center/iam-assume-role-cli/